package com.wfg.myshiro.realm;

import org.apache.shiro.authc.*;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

import java.util.HashSet;

/**
 * myshiro
 *
 * @Title: com.wfg.myshiro.realm
 * @Date: 2020/12/26 0026 22:00
 * @Author: wfg
 * @Description:  @Version:
 */
public class MyRealm2 extends AuthorizingRealm {
    /**
     * 用户授权的方法,当用户认证通过每次访问需要授权的请求时都需要执行这段代码来完成
     *  * 曾授权操作,这里应该查询数据库来获取当前用户的所有角色和权限并设置到shiro中
     *  *
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("---------授权了------------");
        //获取用户的账号,根据账号从数据库中获取数据
        Object obj = principalCollection.getPrimaryPrincipal();
        //定义用户角色的set集合应该来自数据库
        //注意:由于每次点击需要授权的请求时,shiro都会执行这个方法,因此如果这里的数据是来自数据库中的
        //那么一定控制好不能每次都从数据库中获取数据这样的效率太低了
        HashSet<String> roles = new HashSet<>();
        //设置角色,这里操作应该是用数据库中读取数据
        System.out.println(obj+"===================");
        if("admin".equals(obj)){
            roles.add("admin");
            //roles.add("user");
        }
        if("user".equals(obj)){
            roles.add("user");
        }
        //认证信息
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        //SimpleAuthenticationInfo info = new SimpleAuthenticationInfo();
        info.setRoles(roles);
        return info;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) authenticationToken;
        String username = usernamePasswordToken.getUsername();
        char[] password = usernamePasswordToken.getPassword();
        System.out.println(username+"===="+new String(password));

        //不存在的账号
        if(!"admin".equals(username)&&!"zhangsan".equals(username)){
            throw new UnknownAccountException("没找到想要的账号");
        }
        //根据不同的情况进行往外逻辑判断抛出相应的异常既可
        if("zhangsan".equals(username)){
            //throw new LockedAccountException("账号被锁定");
        }
        /**
         * 实际生产环境中我们这样的加密是没有意义的
         * 因为我们主要是在前段访问后端的时候,防止在中间截取或者篡改数据
         * shiro提供这个算法主要是为了在注册的时候使用
         * 我们这里就是为了学习,不太深究了
         */
        //针对页面输入的的密码进行加密
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher("MD5");
        hashedCredentialsMatcher.setHashIterations(2);
        this.setCredentialsMatcher(hashedCredentialsMatcher);
        //针对数据库密码进行加密
        SimpleHash simpleHash2 = new SimpleHash("MD5", "123456", "", 2);

        /**
         * 创建密码认证对象，有shiro 完成认证操作
         * 参数一: 用户名数据库或者前台页面传入的均可
         * 参数二:是从数据库中查询到的密码
         * 参数三:为当前realm的名字
         *
         *
         */
        return new SimpleAuthenticationInfo(username,simpleHash2,getName());
    }
}
